/*
 * @Author: YueLia
 * @Date: 2025-02-21 11:03:07
 * @LastEditors: YueLia
 * @LastEditTime: 2025-02-21 13:52:44
 * @Description:
 */
import { Component, ErrorInfo, ReactNode } from "react";
interface ErrorBoundaryProps {
  children: ReactNode;
}
interface ErrorBoundaryState {
  hasError: boolean;
  error?: String;
  errorInfo?: String | null;
  detailOpen?: boolean;
}
import { Alert, Button, Space } from "antd";
import {
  CaretDownOutlined,
  ReloadOutlined,
  CaretRightOutlined,
} from "@ant-design/icons";
class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = {
      hasError: false,
      error: "",
      errorInfo: "",
      detailOpen: false,
    };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    console.log("getDerivedStateFromError", error);
    return { hasError: true };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    this.setState({
      error: error.message,
      errorInfo: errorInfo.componentStack,
    });
  }

  detailOpenFn = () => {
    this.setState({ detailOpen: !this.state.detailOpen });
  };
  resetFn = () => {
    this.setState({ hasError: false, detailOpen: false });
  };

  render() {
    const { hasError, error, errorInfo, detailOpen } = this.state;
    if (hasError) {
      return (
        <Alert
          message={`组件渲染错误：${error}`}
          description={
            <div>
              <Space>
                <Button
                  type="primary"
                  icon={
                    detailOpen ? <CaretDownOutlined /> : <CaretRightOutlined />
                  }
                  onClick={this.detailOpenFn}
                >
                  错误详情
                </Button>
                <Button
                  type="primary"
                  icon={<ReloadOutlined />}
                  onClick={this.resetFn}
                >
                  再试一次
                </Button>
              </Space>
              {detailOpen && <p>{`${errorInfo}`}</p>}
            </div>
          }
          type="error"
        />
      );
    }
    return this.props.children;
  }
}
export default ErrorBoundary;
